<script lang="ts">
	import { setContext } from 'svelte';
	import { RADIO_GROUP_CONTEXT_KEY } from './context';
	import type { RadioGroupContext, RadioRegistry, Variant } from './types';

	let {
		modelValue = $bindable(),
		disabled = false,
		name = '',
		size = 'md',
		variant = 'primary',
		className = '',
		buttonStyle = false,
		border = false,
		fill = '',
		textColor = '',
		onchange = () => {},
		children = () => {}
	} = $props<{
		modelValue?: any;
		disabled?: boolean;
		name?: string;
		size?: 'sm' | 'md' | 'lg';
		variant?: Variant;
		className?: string;
		buttonStyle?: boolean;
		border?: boolean;
		fill?: string;
		textColor?: string;
		onchange?: (value: any) => void;
		children?: () => any;
	}>();

	const radios = new Set<RadioRegistry>();

	// 将 register 和 onToggle 定义为稳定的函数，不依赖于 effect
	const register = (radio: RadioRegistry) => {
		radios.add(radio);
		radio.updateChecked(modelValue === radio.value);
		return () => {
			radios.delete(radio);
		};
	};

	const onToggle = (value: any) => {
		modelValue = value;
		radios.forEach((radio) => {
			radio.updateChecked(radio.value === value);
		});
		onchange(value);
	};

	// 创建一个稳定的上下文对象
	const groupContext: RadioGroupContext = {
		get disabled() {
			return disabled;
		},
		get name() {
			return name;
		},
		get size() {
			return size;
		},
		get variant() {
			return variant;
		},
		get buttonStyle() {
			return buttonStyle;
		},
		get border() {
			return border;
		},
		get fill() {
			return fill;
		},
		get textColor() {
			return textColor;
		},
		register,
		onToggle
	};

	setContext(RADIO_GROUP_CONTEXT_KEY, groupContext);

	// 监听 modelValue 变化，同步所有 radio 的选中状态
	$effect(() => {
		const value = modelValue;
		radios.forEach((radio) => {
			radio.updateChecked(radio.value === value);
		});
	});
</script>

<div class={`radio-group ${buttonStyle ? 'radio-group--button' : ''} ${className}`}>
	{@render children()}
</div>

<style lang="scss" scoped>
	.radio-group {
		display: inline-flex;
		flex-direction: row;
		gap: 16px;
		align-items: center;
		&.radio-group--button {
			gap: 0;
			margin: 0;
			border-radius: 0;
			border: 1px solid var(--color-info-300);

			&:first-child {
				border-top-left-radius: 4px;
				border-bottom-left-radius: 4px;
			}

			&:last-child {
				border-top-right-radius: 4px;
				border-bottom-right-radius: 4px;
			}

			&:not(:first-child) {
				border-left: none;
			}
		}
	}
</style>
